package utility.zip;

import utils.UtilIO;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


/**
 * 通过Java的Zip输入输出流实现压缩和解压文件
 * @author E440
 *
 */
public class ZipUtil {

	private ZipUtil(){
		
	}
	
	/**
	 * 如果压缩的是文件：a.xx.exe ->a.xx.zip  
	 * 如果压缩的是目录: c:\1  ->c:\1.zip
	 * @param filePath 待压缩路径
	 * @return
	 * @throws IOException 
	 */
	/**
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public static File zip(String filePath) throws IOException {
		File target=null;
		File source=new File(filePath);
		
		if(source.isFile()){
			String prefixName=filePath.substring(0, filePath.lastIndexOf("."));
			target=new File(prefixName+".zip");
		}else{
			target=new File(source.getCanonicalPath()+".zip");
		}
		
		if(target.exists()){
			target.delete();
		}
		
		FileOutputStream fos=new FileOutputStream(target);
		ZipOutputStream zos=new ZipOutputStream(fos);
		addZipEntry("/", source, zos);
		
		return target;
	}
	
	/** 递归调用压缩
	 * @param basePath
	 * @param source
	 * @param zos
	 * @throws IOException 
	 */
	private static void addZipEntry(String basePath, File source,
			ZipOutputStream zos) throws IOException {
		// TODO Auto-generated method stub
		
		if(source.isDirectory()){
			String dir=basePath+source.getName()+"/";
			System.out.println("******** in dir ********");
			System.out.println("source = "+source);
			System.out.println("dirName = " + dir);
			zos.putNextEntry(new ZipEntry(dir));
			zos.closeEntry();
			System.out.println();
			for(File file:source.listFiles()){
				addZipEntry(dir,file,zos);
			}
		}else{
			String entry=basePath+source.getName();
			FileInputStream fis = null;
			BufferedInputStream bis = null;
			try {
				byte[] buffer = new byte[1024 * 10];
				System.out.println("***** in file *****");
				System.out.println("source = "+source);
				System.out.println("entry = "+ entry);
				System.out.println();
				fis = new FileInputStream(source);
				bis = new BufferedInputStream(fis, buffer.length);
				int read = 0;
				zos.putNextEntry(new ZipEntry(entry));
				while ((read = bis.read(buffer, 0, buffer.length)) != -1) {
					zos.write(buffer, 0, read);
				}
				zos.closeEntry();
			} finally {
				UtilIO.closeQuietly(bis, fis);
			}
		}
	}

	public static void unzip(String fileName) throws IOException{
		File source=new File(fileName);
		if(!source.exists()){
			throw new IOException("未找到'"+fileName+"'的文件.");
		}
		if(source.isDirectory()){
			throw new RuntimeException(fileName+" 为目录，无法解压.");
		}
		FileInputStream fis=new FileInputStream(source);
		BufferedOutputStream bos=null;
		byte[] buff=new byte[1024*1024*5];
		String basePath=source.getParent();
		ZipInputStream zis=new ZipInputStream(fis);
		ZipEntry entry=null;
		while((entry=zis.getNextEntry())!=null){
			System.out.println("*********************");
			System.out.println("entry = "+basePath+ entry.getName());
			System.out.println();
			File file=new File(basePath,entry.getName());
			
			
			if(entry.isDirectory()){
				file.mkdir();
			}else{
				bos=new BufferedOutputStream(new FileOutputStream(file));
				int len;
				while((len=zis.read(buff, 0, buff.length))!=-1){
					bos.write(buff, 0, len);
				}
				UtilIO.closeQuietly(bos);
			}
		}
		UtilIO.closeQuietly(zis);
	}
	
	public static void main(String[] arg) throws IOException{
		/*File source1=new File("d:/");
		File source2=new File("D:/temp");
		File source4=new File("D:/temp/");
		File source3=new File("D:/temp/11.xls");
		File source5=new File("D:\\temp\\empty");
		System.out.println(source1.isDirectory());
		System.out.println(source2.isDirectory());
		System.out.println(source4.isDirectory());
		System.out.println(source4.getCanonicalPath());
		System.out.println(source4.getAbsolutePath());
		System.out.println(source1.getParent());
		System.out.println(source2.getParent());
		System.out.println(source3.getParent());
		System.out.println(source1.getName());
		System.out.println(source2.getName());
		System.out.println(source3.getName());
		System.out.println(source4.getName());
		System.out.println(source5.getName());*/
		
		String targetPath = "D:/temp";
		File zipFile=new File(targetPath+".zip");
		//File file = ZipUtil.zip(targetPath);
		ZipUtil.unzip(targetPath+".zip");
		
	}
	
}


